"""
用户认证相关API路由
包括注册、登录、用户管理等功能
"""

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
from typing import Optional
import bcrypt
import jwt
import os

from ..dependencies import get_db, get_current_user
from ..models import (
    # 数据库模型
    User, Company, CandidateProfile, HRProfile,
    # Pydantic模型
    UserCreate, UserLogin, UserResponse, TokenResponse,
    CandidateProfileCreate, HRProfileCreate,
    CompanyCreate, CompanyResponse
)

router = APIRouter(prefix="/auth", tags=["用户认证"])

# JWT设置
SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-secret-key-here")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))

def get_password_hash(password: str) -> str:
    """生成密码哈希"""
    return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """创建访问令牌"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

def authenticate_user(db: Session, username: str, password: str):
    """认证用户"""
    user = db.query(User).filter(User.username == username).first()
    if not user:
        return False
    if not verify_password(password, user.hashed_password):
        return False
    return user

@router.post("/register", response_model=UserResponse)
async def register_user(
    user_data: UserCreate,
    db: Session = Depends(get_db)
):
    """用户注册"""
    # 检查用户名是否已存在
    existing_user = db.query(User).filter(
        (User.username == user_data.username) | (User.email == user_data.email)
    ).first()
    
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名或邮箱已存在"
        )
    
    # 处理公司创建（如果是HR用户）
    company_id = None
    if user_data.user_type.value == "hr" and user_data.company_name:
        # 检查公司是否已存在
        existing_company = db.query(Company).filter(Company.name == user_data.company_name).first()
        if existing_company:
            company_id = existing_company.id
        else:
            # 创建新公司
            new_company = Company(name=user_data.company_name)
            db.add(new_company)
            db.flush()  # 获取ID但不提交
            company_id = new_company.id
    
    # 创建用户
    hashed_password = get_password_hash(user_data.password)
    new_user = User(
        email=user_data.email,
        username=user_data.username,
        hashed_password=hashed_password,
        user_type=user_data.user_type.value,
        company_id=company_id
    )
    
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    
    return new_user

@router.post("/token", response_model=TokenResponse)
async def login_for_access_token(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: Session = Depends(get_db)
):
    """用户登录获取令牌"""
    user = authenticate_user(db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    
    return TokenResponse(
        access_token=access_token,
        token_type="bearer",
        expires_in=ACCESS_TOKEN_EXPIRE_MINUTES * 60,
        user=user
    )

@router.post("/login", response_model=TokenResponse)
async def login_user(
    login_data: UserLogin,
    db: Session = Depends(get_db)
):
    """用户登录（JSON格式）"""
    user = authenticate_user(db, login_data.username, login_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误"
        )
    
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    
    return TokenResponse(
        access_token=access_token,
        token_type="bearer",
        expires_in=ACCESS_TOKEN_EXPIRE_MINUTES * 60,
        user=user
    )

@router.get("/me", response_model=UserResponse)
async def read_users_me(current_user: User = Depends(get_current_user)):
    """获取当前用户信息"""
    return current_user

@router.post("/candidate/profile")
async def create_candidate_profile(
    profile_data: CandidateProfileCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """创建候选人档案"""
    if current_user.user_type != "candidate":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有求职者可以创建候选人档案"
        )
    
    # 检查是否已有档案
    existing_profile = db.query(CandidateProfile).filter(
        CandidateProfile.user_id == current_user.id
    ).first()
    
    if existing_profile:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="候选人档案已存在"
        )
    
    # 创建档案
    profile = CandidateProfile(
        user_id=current_user.id,
        **profile_data.dict()
    )
    
    db.add(profile)
    db.commit()
    db.refresh(profile)
    
    return {"message": "候选人档案创建成功", "profile_id": profile.id}

@router.post("/hr/profile")
async def create_hr_profile(
    profile_data: HRProfileCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """创建HR档案"""
    if current_user.user_type != "hr":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有HR可以创建HR档案"
        )
    
    # 检查是否已有档案
    existing_profile = db.query(HRProfile).filter(
        HRProfile.user_id == current_user.id
    ).first()
    
    if existing_profile:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="HR档案已存在"
        )
    
    # 创建档案
    profile = HRProfile(
        user_id=current_user.id,
        **profile_data.dict()
    )
    
    db.add(profile)
    db.commit()
    db.refresh(profile)
    
    return {"message": "HR档案创建成功", "profile_id": profile.id}

@router.post("/company", response_model=CompanyResponse)
async def create_company(
    company_data: CompanyCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """创建公司"""
    if current_user.user_type != "hr":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有HR可以创建公司"
        )
    
    # 检查公司名是否已存在
    existing_company = db.query(Company).filter(Company.name == company_data.name).first()
    if existing_company:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="公司名已存在"
        )
    
    # 创建公司
    company = Company(**company_data.dict())
    db.add(company)
    db.commit()
    db.refresh(company)
    
    # 更新用户的公司关联
    current_user.company_id = company.id
    db.commit()
    
    return company

@router.get("/company", response_model=CompanyResponse)
async def get_user_company(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取用户关联的公司信息"""
    if not current_user.company_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未关联公司"
        )
    
    company = db.query(Company).filter(Company.id == current_user.company_id).first()
    if not company:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="公司不存在"
        )
    
    return company

@router.put("/company")
async def update_company(
    company_data: CompanyCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """更新公司信息"""
    if current_user.user_type != "hr" or not current_user.company_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有关联公司的HR可以更新公司信息"
        )
    
    company = db.query(Company).filter(Company.id == current_user.company_id).first()
    if not company:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="公司不存在"
        )
    
    # 更新公司信息
    for field, value in company_data.dict().items():
        if value is not None:
            setattr(company, field, value)
    
    db.commit()
    db.refresh(company)
    
    return {"message": "公司信息更新成功"}

@router.delete("/account")
async def delete_account(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """删除用户账户"""
    # 删除相关档案
    if current_user.user_type == "candidate":
        profile = db.query(CandidateProfile).filter(
            CandidateProfile.user_id == current_user.id
        ).first()
        if profile:
            db.delete(profile)
    elif current_user.user_type == "hr":
        profile = db.query(HRProfile).filter(
            HRProfile.user_id == current_user.id
        ).first()
        if profile:
            db.delete(profile)
    
    # 删除用户
    db.delete(current_user)
    db.commit()
    
    return {"message": "账户已删除"}

@router.post("/change-password")
async def change_password(
    old_password: str,
    new_password: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """修改密码"""
    # 验证旧密码
    if not verify_password(old_password, current_user.hashed_password):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="原密码错误"
        )
    
    # 更新密码
    current_user.hashed_password = get_password_hash(new_password)
    current_user.updated_at = datetime.utcnow()
    db.commit()
    
    return {"message": "密码修改成功"}